import { defineStore } from 'pinia'
import { loginByUserName, loginByPhone, logout } from '../api/user'
import router from '../router'
import { ElMessage } from 'element-plus'
import CryptoJS from 'crypto-js'

export const useUserStore = defineStore('user', {
  state: () => ({
    tokenInfo: JSON.parse(localStorage.getItem('tokenInfo') || '{}'),
    userInfo: JSON.parse(localStorage.getItem('userInfo') || '{}'),
    menuTree: JSON.parse(localStorage.getItem('menuTree') || '[]'),
    dataHash: JSON.parse(localStorage.getItem('dataHash') || '{}')
  }),
  
  getters: {
    isLogin: (state) => state.tokenInfo && state.tokenInfo.isLogin === true,
    loginId: (state) => state.tokenInfo ? state.tokenInfo.loginId : null,
    permissionCodes: (state) => {
      const codes = []
      // 提取menuTree中的所有权限码
      const extractCodes = (menus) => {
        if (!menus || !menus.length) return
        menus.forEach(menu => {
          if (menu.permissionCode) {
            codes.push(menu.permissionCode)
          }
          if (menu.children && menu.children.length) {
            extractCodes(menu.children)
          }
        })
      }
      extractCodes(state.menuTree)
      return codes
    },
    hasPermission: (state) => (permissionCode) => {
      return state.permissionCodes.includes(permissionCode)
    }
  },
  
  actions: {
    // 保存登录信息
    saveLoginInfo(data) {
      console.log(data)
      if (data.token) {
        this.tokenInfo = {
          tokenName: data.token.tokenName,
          tokenValue: data.token.tokenValue,
          isLogin: true  // 确保设置登录状态
        }
        localStorage.setItem('tokenInfo', JSON.stringify(this.tokenInfo))
      }
      
      if (data.userInfo) {
        this.userInfo = data.userInfo
        localStorage.setItem('userInfo', JSON.stringify(data.userInfo))
      }
      
      if (data.menuTree) {
        this.menuTree = data.menuTree
        localStorage.setItem('menuTree', JSON.stringify(data.menuTree))
      }

      if(data.dataHash){
        this.dataHash = data.dataHash
        localStorage.setItem('dataHash', JSON.stringify(data.dataHash))
      }
      
      // 设置本地存储监听
      this.setupStorageListener()
    },
     // 跳转到个人中心
    navigateToProfile() {
      // this.userInfo = null
      router.push('/personalcenter')
    },
    
    // 清除登录信息
    clearLoginInfo() {
      this.tokenInfo = {}
      this.userInfo = {}
      this.menuTree = []
      this.dataHash = {}
      localStorage.removeItem('tokenInfo')
      localStorage.removeItem('userInfo')
      localStorage.removeItem('menuTree')
      localStorage.removeItem('dataHash')
    },
    
    // 用户名登录
    async loginByUserName(username, password) {
      try {
        const res = await loginByUserName({ username, password })
        if (res.data) {
          this.saveLoginInfo(res.data)
          return res
        }
        return Promise.reject(res.message || '登录失败')
      } catch (error) {
        return Promise.reject(error)
      }
    },
    
    // // 手机号登录
    // async loginByPhone(phone, verifyCode) {
    //   try {
    //     const res = await loginByPhone({ phone, verifyCode })
    //     if (res.data) {
    //       this.saveLoginInfo(res.data)
    //       return res
    //     }
    //     return Promise.reject(res.message || '登录失败')
    //   } catch (error) {
    //     return Promise.reject(error)
    //   }
    // },
    
    // 退出登录
    async logout() {
      try {
        await logout()
        // 移除存储监听
        window.removeEventListener('storage', this.handleStorageChange)
        
        // 清除用户信息
        this.clearLoginInfo()
        
        // 清除权限和路由缓存
        const { usePermissionStore } = await import('./permission')
        const permissionStore = usePermissionStore()
        permissionStore.resetRoutes()
        
        // 重新加载页面，确保所有路由被重置
        window.location.reload()
        
        return Promise.resolve()
      } catch (error) {
        return Promise.reject(error)
      }
    },
    
    // 设置localStorage变化监听，检测篡改
    setupStorageListener() {
      // 移除之前的监听器，避免重复添加
      window.removeEventListener('storage', this.handleStorageChange)
      window.addEventListener('storage', this.handleStorageChange)
      
      // 也在当前页面监听localStorage的变化
      const originalSetItem = localStorage.setItem
      localStorage.setItem = function(key, value) {
        const event = new Event('storage')
        event.key = key
        event.newValue = value
        window.dispatchEvent(event)
        originalSetItem.apply(this, arguments)
      }
      
      const originalRemoveItem = localStorage.removeItem
      localStorage.removeItem = function(key) {
        const event = new Event('storage')
        event.key = key
        event.newValue = null
        window.dispatchEvent(event)
        originalRemoveItem.apply(this, arguments)
      }
    },
    
    // 处理localStorage变化事件
    handleStorageChange(event) {
      const store = useUserStore()
      if (!store.isLogin) return
      
      // 检查关键存储是否被修改
      if (['tokenInfo', 'userInfo', 'menuTree'].includes(event.key)) {
        if (event.newValue === null) {
          // 存储被删除
          console.warn('检测到关键存储被删除:', event.key)
          store.forceRelogin('检测到安全异常，请重新登录')
        } else {
          // 数据被修改，需要验证完整性
          console.warn('检测到关键数据被修改:', event.key)
          store.verifyDataIntegrity()
        }
      } else if (event.key === 'dataHash') {
        // 哈希值被修改或删除，直接登出
        console.warn('检测到数据哈希被修改')
        store.forceRelogin('检测到安全异常，请重新登录')
      }
    },
    
    // 验证数据完整性 - 本地验证机制
    async verifyDataIntegrity() {
      try {
        // 本地验证，使用dataHash中的预验证密钥
        const storedHash = JSON.parse(localStorage.getItem('dataHash') || '{}');
        const storedUserInfo = JSON.parse(localStorage.getItem('userInfo') || '{}');
        const storedMenuTree = JSON.parse(localStorage.getItem('menuTree') || '[]');
        
        // 如果没有哈希数据或验证密钥，直接强制登录
        if (!storedHash || !storedHash.value || !storedHash.verifyKey) {
          this.forceRelogin('安全验证失败，请重新登录');
          return false;
        }
        
        // 对菜单树使用压缩算法得到更紧凑的表示
        let menuTreeCompressed;
        try {
          // 先将菜单树转为JSON字符串，但需要预处理时间格式
          // 深度复制菜单树并标准化时间格式
          const normalizedMenuTree = JSON.parse(JSON.stringify(storedMenuTree, (key, value) => {
            // 检测时间戳字符串并转换为数值时间戳
            if (typeof value === 'string' && 
                (key.includes('Time') || key.includes('Date')) && 
                /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) {
              // 将ISO格式时间转换为时间戳数值
              return new Date(value).getTime();
            }
            return value;
          }));
          
          // 将标准化后的菜单树转为JSON
          const menuTreeJson = JSON.stringify(normalizedMenuTree);
          
          // 使用CryptoJS的Base64编码压缩数据
          const wordArray = CryptoJS.enc.Utf8.parse(menuTreeJson);
          // 再计算MD5得到固定长度的哈希值作为指纹
          //转化大写
          menuTreeCompressed = CryptoJS.MD5(wordArray).toString(CryptoJS.enc.Hex).toUpperCase();
        } catch (e) {
          // 压缩失败时使用简单的长度表示
          menuTreeCompressed = storedMenuTree.length.toString();
          console.error('菜单树压缩失败:', e);
        }
        
        const stringToHash = 
          `userId:${storedUserInfo.id}|` + 
          `username:${storedUserInfo.username}|` + 
          `menuTreeSize:${menuTreeCompressed}`;
        
        console.log("验证字符串:", stringToHash);
        
        // 使用HMAC-SHA256计算本地哈希
        const localVerificationHash = CryptoJS.HmacSHA256(
          stringToHash,
          storedHash.verifyKey
        ).toString(CryptoJS.enc.Hex).toUpperCase();
        
        // 与前端验证哈希比较
        if (storedHash.frontendVerifyHash !== localVerificationHash) {
          console.log("计算哈希", localVerificationHash);
          console.log("存储哈希", storedHash.frontendVerifyHash);
          console.warn('本地验证失败: 哈希值不匹配');
          this.forceRelogin('数据完整性验证失败，请重新登录');
          return false;
        }
        
        // 更新状态以保持同步
        this.dataHash = storedHash;
        this.userInfo = storedUserInfo;
        this.menuTree = storedMenuTree;
        
        return true;
      } catch (error) {
        console.error('数据完整性验证错误:', error);
        this.forceRelogin('数据完整性验证发生错误，请重新登录');
        return false;
      }
    },
    
    
    // 强制重新登录
    forceRelogin(message) {
      // 显示提示信息
      ElMessage.error(message || '安全异常，请重新登录')
      
      // 清除所有数据
      this.clearLoginInfo()
      
      // 移除存储监听
      window.removeEventListener('storage', this.handleStorageChange)
      
      // 重定向到登录页
      setTimeout(() => {
        router.push('/login')
      }, 1500)
    },
    
    // 初始化，在应用启动时调用
    async initializeStore() {
      // 如果已登录，进行数据完整性验证
      if (this.isLogin) {
        const isValid = await this.verifyDataIntegrity()
        if (!isValid) {
          console.warn('初始化时数据完整性验证失败')
          return false
        }
        
        // 设置存储监听
        this.setupStorageListener()
      }
      return true
    }
  }
}) 